package com.kinroy.briefreport.service.serviceimpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kinroy.briefreport.dto.Result;
import com.kinroy.briefreport.entity.Note;
import com.kinroy.briefreport.entity.NoteLog;
import com.kinroy.briefreport.entity.Task;
import com.kinroy.briefreport.enums.note.NoteStatus;
import com.kinroy.briefreport.enums.note.NoteType;
import com.kinroy.briefreport.mapper.NoteLogMapper;
import com.kinroy.briefreport.mapper.NoteMapper;
import com.kinroy.briefreport.service.INoteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.*;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * @author kinroy
 */
@Service
public class NoteServiceImpl extends ServiceImpl<NoteMapper, Note> implements INoteService {

    public static final String SAVE_BUT_NOT_PUBLISH = "保存未发布";

    public static final String SAVE_PUBLISH = "发布";

    public static final String SAVE_REGULARLY_PUBLISH = "定时发布";

    public static final String SAVE_EDIT = "编辑保存";
    public static final String DEL_NOTE = "删除日志";

    public static final String NOTE_TASK_QUEUE_NAME = "noteQueue";


    @Autowired
    private NoteMapper noteMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private NoteLogMapper noteLogMapper;


    /**
     * 日志发布功能
     * 当日已经发布了日志变不能再次提交（日报每天一次，周报每周一次，月度总结每月一次）
     *
     * @param note
     * @return
     */
    @Override
    @Transactional
    public Result publishNote(Note note) throws Exception {
        //前端传来表单数据，封装好了大部分信息，我们需要操作的就是根据noteStatus来判断是后续操作

        //kinroy 2024.1.30 新增业务:如果是编辑日志的，则前端传来的数据会有noteId，则走编辑的逻辑
        if (note.getNoteId() != null) {
            switch (note.getNoteType()) {
                case 0:

                    /*kinory 2024.1.30 新增业务：如果是保存日志的话，就是不需要判断提交*/
                    if (note.getNoteStatus() == NoteStatus.SAVE_BUT_NOT_PUBLISH.getCode()) {
                        break;
                    }
                    //判断今日日报是否已经发布了
                    LocalDate today = LocalDate.now();
                    LocalDateTime minNightTime = today.atStartOfDay();
                    Note noteAfterThisTime = noteMapper.getNoteAfterThisTime(minNightTime, note.getPublishUserId(), NoteType.Daily.getCode());
                    if (noteAfterThisTime != null) {
                        return Result.fail("今日日报已提交，请勿重复提交或者定时提交日报！");
                    }
                    break;
                case 1:
                    /*kinory 2024.1.30 新增业务：如果是保存日志的话，就是不需要判断提交*/
                    if (note.getNoteStatus() == NoteStatus.SAVE_BUT_NOT_PUBLISH.getCode()) {
                        break;
                    }
                    //判断这周的周报是否已经发布了
                    //1.获取本周开始时间
                    LocalDate nowDay = LocalDate.now();
                    LocalDate startOfWeek = nowDay.with(DayOfWeek.MONDAY);
                    LocalDateTime start = startOfWeek.atStartOfDay();
                    //2.获取本周结束时间
                    LocalDate nowDay1 = LocalDate.now();
                    LocalDate endOfWeek = nowDay1.with(DayOfWeek.FRIDAY);
                    LocalDateTime end = endOfWeek.atTime(23, 59, 59, 999999999);
                    Note nodeBetweenTheTime = noteMapper.getNodeBetweenTheTime(start, end, note.getPublishUserId(), NoteType.Weekly.getCode());
                    if (nodeBetweenTheTime != null) {
                        return Result.fail("本周周报已提交，请勿重复提交！");
                    }
                    break;
                case 2:
                    /*kinory 2024.1.30 新增业务：如果是保存日志的话，就是不需要判断提交*/
                    if (note.getNoteStatus() == NoteStatus.SAVE_BUT_NOT_PUBLISH.getCode()) {
                        break;
                    }
                    //判断这个月的月度总结是否已经发布了
                    LocalDate today1 = LocalDate.now();
                    LocalDate startOfMonth = today1.with(TemporalAdjusters.firstDayOfMonth());
                    LocalDateTime startDate = startOfMonth.atStartOfDay();

                    LocalDate today2 = LocalDate.now();
                    LocalDate endOfMonth = today2.with(TemporalAdjusters.lastDayOfMonth());
                    LocalDateTime endDate = endOfMonth.atTime(23, 59, 59, 999999999);
                    Note nodeBetweenTheTime1 = noteMapper.getNodeBetweenTheTime(startDate, endDate, note.getPublishUserId(), NoteType.Monthly.getCode());
                    if (nodeBetweenTheTime1 != null) {
                        return Result.fail("本月月度总结已提交，请勿重复提交！");
                    }
                    break;
            }

            //2.根据noteStatus判断后续执行的操作
            if (note.getNoteStatus() == NoteStatus.SAVE_BUT_NOT_PUBLISH.getCode()) {
                //2.1保存但未发布
                /*boolean saveFlag = save(note);*/
                //kinroy 2024.1.31 修改编辑日志时出现的bug
                /*编辑日志时，说明db中已经存在了当前日志，也就是说已经有了主键，
                 * 这个时候，我们要做的是去update对应主键，而不是去insert
                 * */
                /*Boolean save = noteMapper.publishOrSaveNote(note);*/

                boolean saveFlag = updateById(note);
                if (saveFlag) {
                    addNoteLog(note.getNoteId(), SAVE_BUT_NOT_PUBLISH);
                    return Result.ok("日志保存成功!");
                }
                return Result.fail("保存日志失败！");
            } else {

                LocalDateTime publishTime = note.getPublishTime();
                if (publishTime == null) {
                    //立即发布（可能是用户设置了发布时间为当前时间之前或是没有设置发布时间）
                    LocalDateTime current = LocalDateTime.now();
                    note.setPublishTime(current);
                    note.setNoteStatus(NoteStatus.SAVE_PUBLISH.getCode());
                /*kinroy 2024.1.30 修改一下save方法
                调用了mybatis自带的save方法，publishTime不会保存成我们的当前的北京时间，而是会少8个小时
                所以我们要自己写sql
                * */
                    /*boolean save = save(note);*/
                    //kinroy 2024.1.31 修改编辑日志时出现的bug
                    /*编辑日志时，说明db中已经存在了当前日志，也就是说已经有了主键，
                     * 这个时候，我们要做的是去update对应主键，而不是去insert
                     * */
                    /*Boolean save = noteMapper.publishOrSaveNote(note);*/
                    boolean save = updateById(note);
                    if (save) {
                        //添加noteLog数据做日志
                        addNoteLog(note.getNoteId(), SAVE_PUBLISH);
                        return Result.ok("日志发布成功！");
                    } else {
                        Result.fail("日志发布失败！");
                    }
                }
                LocalDateTime currentTime = LocalDateTime.now();
                if (publishTime.isAfter(currentTime)) {
                    //设置了发布时间，但是发布时间是在当前时间之后的，为定时发布

                    //加入redis的NoteQueue中
                    addOrEditNoteTaskToRedis(note);
                    //存入db
                    note.setNoteStatus(NoteStatus.SAVE_REGULARLY_PUBLISH.getCode());

                    //kinroy 2024.1.31 修改编辑日志时出现的bug
                    /*编辑日志时，说明db中已经存在了当前日志，也就是说已经有了主键，
                     * 这个时候，我们要做的是去update对应主键，而不是去insert
                     * */
                    /*Boolean save = noteMapper.publishOrSaveNote(note);*/
                    boolean save = updateById(note);
                    if (save) {
                        //添加noteLog数据做日志
                        addNoteLog(note.getNoteId(), SAVE_REGULARLY_PUBLISH);
                        return Result.ok("日志定时发布成功！");
                    } else {
                        Result.fail("日志定时发布失败！");
                    }
                } else {
                    //立即发布（可能是用户设置了发布时间为当前时间之前或是没有设置发布时间）
                    LocalDateTime current = LocalDateTime.now();
                    note.setPublishTime(current);
                    note.setNoteStatus(NoteStatus.SAVE_PUBLISH.getCode());
                    //kinroy 2024.1.31 修改编辑日志时出现的bug
                    /*编辑日志时，说明db中已经存在了当前日志，也就是说已经有了主键，
                     * 这个时候，我们要做的是去update对应主键，而不是去insert
                     * */
                    /*Boolean save = noteMapper.publishOrSaveNote(note);*/
                    boolean save = updateById(note);
                    if (save) {
                        //添加noteLog数据做日志
                        addNoteLog(note.getNoteId(), SAVE_PUBLISH);
                        return Result.ok("日志发布成功！");
                    } else {
                        Result.fail("日志发布失败！");
                    }
                }
            }
            return Result.fail("未知错误！");
        }

        //1.创建noteId（UUID）
        String noteId = UUID.randomUUID().toString();
        note.setNoteId(noteId);

        //kinroy 2024.1.26 新添加的业务逻辑，日志只能提交一次，如果今天的日志在db中有记录则无法再提交、
        switch (note.getNoteType()) {
            case 0:

                /*kinory 2024.1.30 新增业务：如果是保存日志的话，就是不需要判断提交*/
                if (note.getNoteStatus() == NoteStatus.SAVE_BUT_NOT_PUBLISH.getCode()) {
                    break;
                }
                //判断今日日报是否已经发布了
                LocalDate today = LocalDate.now();
                LocalDateTime minNightTime = today.atStartOfDay();
                Note noteAfterThisTime = noteMapper.getNoteAfterThisTime(minNightTime, note.getPublishUserId(), NoteType.Daily.getCode());
                if (noteAfterThisTime != null) {
                    return Result.fail("今日日报已提交，请勿重复提交或者定时提交日报！");
                }
                break;
            case 1:
                /*kinory 2024.1.30 新增业务：如果是保存日志的话，就是不需要判断提交*/
                if (note.getNoteStatus() == NoteStatus.SAVE_BUT_NOT_PUBLISH.getCode()) {
                    break;
                }
                //判断这周的周报是否已经发布了
                //1.获取本周开始时间
                LocalDate nowDay = LocalDate.now();
                LocalDate startOfWeek = nowDay.with(DayOfWeek.MONDAY);
                LocalDateTime start = startOfWeek.atStartOfDay();
                //2.获取本周结束时间
                LocalDate nowDay1 = LocalDate.now();
                LocalDate endOfWeek = nowDay1.with(DayOfWeek.FRIDAY);
                LocalDateTime end = endOfWeek.atTime(23, 59, 59, 999999999);
                Note nodeBetweenTheTime = noteMapper.getNodeBetweenTheTime(start, end, note.getPublishUserId(), NoteType.Weekly.getCode());
                if (nodeBetweenTheTime != null) {
                    return Result.fail("本周周报已提交，请勿重复提交！");
                }
                break;
            case 2:
                /*kinory 2024.1.30 新增业务：如果是保存日志的话，就是不需要判断提交*/
                if (note.getNoteStatus() == NoteStatus.SAVE_BUT_NOT_PUBLISH.getCode()) {
                    break;
                }
                //判断这个月的月度总结是否已经发布了
                LocalDate today1 = LocalDate.now();
                LocalDate startOfMonth = today1.with(TemporalAdjusters.firstDayOfMonth());
                LocalDateTime startDate = startOfMonth.atStartOfDay();

                LocalDate today2 = LocalDate.now();
                LocalDate endOfMonth = today2.with(TemporalAdjusters.lastDayOfMonth());
                LocalDateTime endDate = endOfMonth.atTime(23, 59, 59, 999999999);
                Note nodeBetweenTheTime1 = noteMapper.getNodeBetweenTheTime(startDate, endDate, note.getPublishUserId(), NoteType.Monthly.getCode());
                if (nodeBetweenTheTime1 != null) {
                    return Result.fail("本月月度总结已提交，请勿重复提交！");
                }
                break;
        }

        //2.根据noteStatus判断后续执行的操作
        if (note.getNoteStatus() == NoteStatus.SAVE_BUT_NOT_PUBLISH.getCode()) {
            //2.1保存但未发布
            //如果没有发布时间，默认给它填一个当前时间
            LocalDateTime now = LocalDateTime.now();
            note.setPublishTime(now);
            boolean saveFlag = save(note);
            if (saveFlag) {
                addNoteLog(noteId, SAVE_BUT_NOT_PUBLISH);
                return Result.ok("日志保存成功!");
            }
            return Result.fail("保存日志失败！");
        } else {

            LocalDateTime publishTime = note.getPublishTime();
            if (publishTime == null) {
                //立即发布（可能是用户设置了发布时间为当前时间之前或是没有设置发布时间）
                LocalDateTime current = LocalDateTime.now();
                note.setPublishTime(current);
                note.setNoteStatus(NoteStatus.SAVE_PUBLISH.getCode());
                /*kinroy 2024.1.30 修改一下save方法
                调用了mybatis自带的save方法，publishTime不会保存成我们的当前的北京时间，而是会少8个小时
                所以我们要自己写sql
                * */
                /*boolean save = save(note);*/
                Boolean save = noteMapper.publishOrSaveNote(note);
                if (save) {
                    //添加noteLog数据做日志
                    addNoteLog(noteId, SAVE_PUBLISH);
                    return Result.ok("日志发布成功！");
                } else {
                    Result.fail("日志发布失败！");
                }
            }
            LocalDateTime currentTime = LocalDateTime.now();
            if (publishTime.isAfter(currentTime)) {
                //设置了发布时间，但是发布时间是在当前时间之后的，为定时发布

                //加入redis的NoteQueue中
                addOrEditNoteTaskToRedis(note);
                //存入db
                note.setNoteStatus(NoteStatus.SAVE_REGULARLY_PUBLISH.getCode());
                Boolean save = noteMapper.publishOrSaveNote(note);
                if (save) {
                    //添加noteLog数据做日志
                    addNoteLog(noteId, SAVE_REGULARLY_PUBLISH);
                    return Result.ok("日志定时发布成功！");
                } else {
                    Result.fail("日志定时发布失败！");
                }
            } else {
                //立即发布（可能是用户设置了发布时间为当前时间之前或是没有设置发布时间）
                LocalDateTime current = LocalDateTime.now();
                note.setPublishTime(current);
                note.setNoteStatus(NoteStatus.SAVE_PUBLISH.getCode());
                Boolean save = noteMapper.publishOrSaveNote(note);
                if (save) {
                    //添加noteLog数据做日志
                    addNoteLog(noteId, SAVE_PUBLISH);
                    return Result.ok("日志发布成功！");
                } else {
                    Result.fail("日志发布失败！");
                }
            }
        }
        return Result.fail("未知错误！");
    }

    /**
     * 获取我当前publishUserid对应用户的日志
     * 通过条件查询获取并且分页返回
     *
     * @param publishUserid
     * @param currentPage
     * @param pageSize
     * @param noteStatusSelectValue
     * @param noteTypeSelectValue
     * @return
     */
    @Override
    public Result getNoteConditionalQueryByPage(Long publishUserid, Long currentPage, Long pageSize, Integer noteStatusSelectValue, Integer noteTypeSelectValue, LocalDateTime publishTime, Integer queryType, String noteNameSelectValue) {
        //1.查询条件绑定(前端传-1 则就是查询全部)
        LambdaQueryWrapper<Note> wrapper = new LambdaQueryWrapper<>();
        if (queryType == 1) {
            wrapper.eq(noteStatusSelectValue != null && noteStatusSelectValue != 3, Note::getNoteStatus, noteStatusSelectValue);
        } else if (queryType == 2) {
            //不分页的查询的业务需求只在未发布日志这个模块，所有把状态设为
            Integer[] selectStatusArr
                    = {NoteStatus.SAVE_REGULARLY_PUBLISH.getCode(), NoteStatus.SAVE_BUT_NOT_PUBLISH.getCode()};
            wrapper.in(Note::getNoteStatus, selectStatusArr);
        }
        // 修改bug，新增查询条件当前查询用户的id
        wrapper.eq(publishUserid!=null,Note::getPublishUserId,publishUserid);
        wrapper.eq(noteTypeSelectValue != null, Note::getNoteType, noteTypeSelectValue);
        wrapper.ge(publishTime != null, Note::getPublishTime, publishTime);
        wrapper.like(noteNameSelectValue != null && noteNameSelectValue != "", Note::getNoteName, noteNameSelectValue);

        //kinroy 2024.1.27 新增业务：当QueryType==1 走分页逻辑，当QueryType==2 的时候，走普通条件查询逻辑
        if (queryType == 2) {
            List<Note> noteList = list(wrapper);
            if (noteList != null) {
                return Result.ok(noteList);
            } else {
                return Result.fail("查询失败！");
            }
        } else if (queryType == 1) {
            //2.分页查询
            wrapper.orderByDesc(Note::getCreateTime);
            Page<Note> notePage = new Page<>(currentPage, pageSize);
            Page<Note> page = this.page(notePage, wrapper);

            //3.返回前端数据： 1.当前页面数据  2.数据总页数
            List<Note> records = page.getRecords();
            long total = page.getTotal();
            Map<String, Object> reslut = new HashMap<>();
            reslut.put("pageData", records);
            reslut.put("totalData", total);
            return Result.ok(reslut);
        }
        return Result.fail("查询失败！");
    }


    /**
     * 查tb_note表，返回相应的note数据
     * 同时查询note_image_relation表，返回与note绑定的图片数据
     *
     * @param noteId
     * @return
     */
    @Override
    public Result getNoteAllInfoByNoteId(String noteId) {
        //1.查询tb_note表获取相应的数据
        Note noteById = new Note();
        try {
            noteById = getById(noteId);
            //2.查询note_image_relation获取相应图片
            List<String> noteImagesByNoteId = noteMapper.getNoteImagesByNoteId(noteId);
            noteById.setNoteImages(noteImagesByNoteId);
            return Result.ok(noteById);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("noteId不能为空！");
        }

    }

    /**
     * 修改note的内容
     * 可修改的部分有（noteName，noteType，noteContent，publishTime）
     * 已发的日志是无法修改内容的，不论是userRole是部门领导（1）还是员工（3）、项目组长（2）
     *
     * @param note
     * @return
     */
    @Override
    @Transactional
    public Result editNoteByNoteId(Note note) {
        //1.除了修改了publishTime，其他的修改内容均可以直接修改db中的对应数据即可
        String noteId = note.getNoteId();
        LocalDateTime afterEditPublishTime = note.getPublishTime();
        LocalDateTime publishTime = getById(noteId).getPublishTime();
        LocalDateTime now = LocalDateTime.now();
        ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();


        //kinroy 2024.1.25 添加功能是判断note是否已经发布，发布之后无法进行任何修改

        Note byId = getById(noteId);
        if (byId.getNoteStatus() == NoteStatus.SAVE_PUBLISH.getCode()) {
            return Result.fail("已发布的日志无法修改！");
        }


        if (note.getNoteStatus() == NoteStatus.SAVE_BUT_NOT_PUBLISH.getCode()) {
            //保存但未发布状态的文章，直接修改即可
            boolean flag = updateById(note);
            if (flag) {
                try {
                    addNoteLog(noteId, SAVE_EDIT);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return Result.ok();
            } else {
                return Result.fail("修改日志失败！");
            }

        }

        if (afterEditPublishTime.isEqual(publishTime)) {
            /*
             * 用户修改了发布时间，晚于或者是早于db中存储的发布时间，但是没有比当前时间早，
             * 则需要更新redis中noteQueue中的数据
             * */
            long changeScore = afterEditPublishTime.toEpochSecond(ZoneOffset.UTC);
            zSetOperations.add(NOTE_TASK_QUEUE_NAME, noteId, changeScore);
            boolean flag = updateById(note);
            if (flag) {
                try {
                    addNoteLog(noteId, SAVE_EDIT);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return Result.ok("修改日志成功！");
            } else {
                return Result.fail("修改日志失败！");
            }


        } else if (afterEditPublishTime.isBefore(now)) {
            /*
             * 用户修改了发布时间，早于了当前时间，则默认此操作为立即发布，删除该条note
             * 在redis中noteQueue中的数据
             * */
            zSetOperations.remove(NOTE_TASK_QUEUE_NAME, note.getNoteId());
            note.setNoteStatus(NoteStatus.SAVE_PUBLISH.getCode());
            boolean flag = updateById(note);
            if (flag) {
                try {
                    addNoteLog(noteId, SAVE_PUBLISH);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return Result.ok("修改日志成功！");
            } else {
                return Result.fail("修改日志失败！");
            }
        } else {
            boolean flag = updateById(note);
            if (flag) {
                try {
                    addNoteLog(noteId, SAVE_PUBLISH);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return Result.ok("修改日志成功！");
            } else {
                return Result.fail("修改日志失败！");
            }
        }
    }

    /**
     * 根据noteId删除对应note
     * 普通员工和项目组长无法删除自己发布了的任务，但是部门领导可以
     *
     * @param noteId
     * @return
     */
    @Override
    public Result delNoteByNoteId(String noteId, Integer role) {

        //部门领导可以删除任何状态下的日志
        if (role == 1) {
            boolean b = removeById(noteId);
            if (b) {
                try {
                    addNoteLog(noteId, DEL_NOTE);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return Result.ok();
            }
        }

        //员工只能删除自己没有发布的日志
        Note byId = getById(noteId);
        if (byId.getNoteStatus() == NoteStatus.SAVE_PUBLISH.getCode()) {
            return Result.fail("发布后的日志无法删除！");
        } else {
            boolean b = removeById(noteId);
            if (b) {
                try {
                    addNoteLog(noteId, DEL_NOTE);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return Result.ok();
            }
        }
        return Result.fail("日志删除失败！");
    }

    /**
     * 获取当前用户未发布的任务并且按照发布时间升序排列返回
     *
     * @param publishUserid
     * @return
     */
    @Override
    public Result getMyUnSubmitNotes(Long publishUserid) {
        if (publishUserid == null) {
            return Result.fail("发布者Id不能为空！");
        }
        LambdaQueryWrapper<Note> wrapper = new LambdaQueryWrapper<Note>();
        wrapper.eq(Note::getPublishUserId, publishUserid);
        Integer[] unSubmitNoteStatusNum = {0, 2};
        wrapper.in(Note::getNoteStatus, unSubmitNoteStatusNum);
        wrapper.orderByAsc(Note::getPublishTime);
        List<Note> unSubmitNotes = list(wrapper);
        return Result.ok(unSubmitNotes);
    }

    /**
     * 根据日志id获取日志，并且分页返回
     *
     * @param noteId
     * @return
     */
    @Override
    public Result getNoteById(String noteId) {
        LambdaQueryWrapper<Note> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(noteId != null && noteId != "", Note::getNoteId, noteId);
        //2.分页查询
        wrapper.orderByDesc(Note::getCreateTime);
        Page<Note> notePage = new Page<>(1, 1);
        Page<Note> page = this.page(notePage, wrapper);

        //3.返回前端数据： 1.当前页面数据  2.数据总页数
        List<Note> records = page.getRecords();
        long total = page.getTotal();
        Map<String, Object> reslut = new HashMap<>();
        reslut.put("pageData", records);
        reslut.put("totalData", total);
        return Result.ok(reslut);
    }

    /**
     * 获取对应日志信息进行展示
     *
     * @param userId
     * @param noteTypeName
     * @return
     */
    @Override
    public Result getNoteDtoToShow(Long userId, String noteTypeName) {
        LambdaQueryWrapper<Note> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Note::getPublishUserId, userId);
        switch (noteTypeName) {
            case "dailyNote":
                wrapper.eq(Note::getNoteType, 0);
                break;
            case "weeklyNote":
                wrapper.eq(Note::getNoteType, 1);
                break;
            case "monthlyNote":
                wrapper.eq(Note::getNoteType, 2);
                break;
            default:
                return Result.fail("未知错误！");
        }
        //按照发布日期去降序排列
        wrapper.orderByDesc(Note::getPublishTime);

        List<Note> noteList = list(wrapper);
        return Result.ok(noteList);
    }

    /**
     * 添加noteLog
     *
     * @param noteId    需要添加log的noteId
     * @param operation 操作描述
     */
    public void addNoteLog(String noteId, String operation) throws Exception {
        NoteLog noteLog = new NoteLog();
        noteLog.setNoteId(noteId);
        NoteLog noteLogByNoteId = null;
        try {
            noteLogByNoteId = noteLogMapper.getLatestNoteLogByNoteId(noteId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (noteLogByNoteId == null) {
            //说明为第一次的日志操作,设置默认值
            noteLog.setOperationVersion(1);
        } else {
            noteLog.setOperationVersion(noteLogByNoteId.getOperationVersion() + 1);
        }
        noteLog.setOperation(operation);
        LocalDateTime currentTime = LocalDateTime.now();
        noteLog.setOperationTime(currentTime);
        int flag = noteLogMapper.insert(noteLog);
        //如果保存不成功，向外抛一个异常方便Db回滚
        if (flag != 1) {
            throw new Exception();
        }
    }

    /**
     * 将定时发布的日志任务加入到redis的zSet中去
     * 或者已经加入redis的日志任务的发布时间
     *
     * @param note
     * @return
     */
    public Boolean addOrEditNoteTaskToRedis(Note note) {
        //1.向redis中的zset加入我们需要定时发布的日志id信息
        ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();
        //2.将note中的publishTime转换成Double，作为我们zset排序的socre
        LocalDateTime publishTime = note.getPublishTime();
        //将日期转换成距离java纪元的秒数(表示从 Epoch（1970年1月1日午夜 UTC）开始的。)

        //kinroy 2024.1.24 :修改一下将距离纪元的秒数转换成分钟数
        long score = publishTime.toEpochSecond(ZoneOffset.UTC);
        return zSetOperations.add(NOTE_TASK_QUEUE_NAME, note.getNoteId(), score);
    }

    /**
     * 根据userId和noteType获取对应用户的某种类型日志的待提交数
     * @param noteType
     * @param publishUserId
     * @return
     */
    public Integer getUnPublishNoteNumByType(Integer noteType,Long publishUserId){
        // 获取当前日期和时间
        LocalDateTime now = LocalDateTime.now();
        // 获取当前日期
        LocalDate currentDate = now.toLocalDate();
        // 获取本周周一的日期
        LocalDate monday = currentDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        LocalDateTime mondayStart = LocalDateTime.of(monday, LocalTime.MIN);
        // 获取本周周五的日期
        LocalDate friday = currentDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY));
        LocalDateTime fridayEnd = LocalDateTime.of(friday, LocalTime.MAX);
        Integer i = noteMapper.countNodeBetweenTheTime(mondayStart, fridayEnd, publishUserId, noteType);
        Integer finalResultCount=0;
        if (noteType.equals(NoteType.Daily.getCode())){
            //finalResultCount=5-i;
            // 修改了一下待提交日报待bug
            finalResultCount = currentDate.getDayOfWeek().getValue() - i;
        }else if (noteType.equals(NoteType.Weekly.getCode())){
            finalResultCount=1-i;
        }
        return finalResultCount;
    }


}
